﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Linq;

namespace Flare.DB.CeEntity
{
    class contract_list : Validation
    {
        [DisplayName("ИД контракта")]
        public int id_contract { get; set; }
        [DisplayName("Номер контракта"), FRequired, FStringLength(50)]
        public string contract_number { get; set; }
        [DisplayName("Вид услуги"), FRequired]
        public int? id_service { get; set; }
        [DisplayName("Поставщик"), FRequired]
        public int? id_provider { get; set; }
        [DisplayName("Отдел"), FRequired]
        public int? id_department { get; set; }
        [DisplayName("Примечание к контракту")]
        public string contract_description { get; set; }
        [DisplayName("Договор закрыт")]
        public bool isclosed { get; set; }
    }
    class contract_provider : Validation
    {
        [DisplayNameAttribute("ИД поставщика услуги")]
        public int id_provider { get; set; }
        [DisplayNameAttribute("Поставщик услуги"), FRequired, FStringLength(50)]
        public string provider { get; set; }
        [DisplayNameAttribute("Адрес"), FRequired]
        public string provider_address { get; set; }
        [DisplayNameAttribute("Номер договора (по умолчанию)"), FRequired, FStringLength(50)]
        public string default_contract_number { get; set; }  
    }
    class contract_providerphone : Validation
    {
        [DisplayNameAttribute("ИД телефона поставщика")]
        public int id_providerphone { get; set; }
        [DisplayNameAttribute("Поставщик услуги"), FRequired]
        public int? id_provider { get; set; }
        [DisplayNameAttribute("Телефон поставщика услуги"), FRequired, FStringLength(50)]
        public string providerphone { get; set; }
        [DisplayNameAttribute("Примечание"), FRequired, FStringLength(100)]
        public string description { get; set; }
    }
    class contract_service : Validation
    {
        [DisplayNameAttribute("ИД вида услуги")]
        public int id_service { get; set; }
        [DisplayNameAttribute("Вид услуги"),FRequired,FStringLength(50)]
        public string service { get; set; }
    }
    class endpoints : Validation
    {
        [DisplayName("ИД точки сети")]
        public int id_endpoint { get; set; }
        [DisplayName("Наименование"), FRequired]
        public string endpoint { get; set; }
        [DisplayName("Тип"), FRequired]
        public int? id_type { get; set; }
        [DisplayName("Кабинет"), FRequired]
        public int? id_room { get; set; }
        [DisplayName("IP адрес"), FRequired, FStringLength(15), FRegExp(@"\d+\.\d+\.\d+\.\d+")]
        public string net_ip { get; set; }
        [DisplayName("Телефон"), FStringLength(50)]
        public string phone { get; set; }
    }
    class endpoint_types : Validation
    {
        [DisplayName("ИД тип")]
        public int id_type { get; set; }
        [DisplayName("Тип узла"),FRequired,FStringLength(50)]
        public string type { get; set; }
    }
    class endpoints_map : Validation
    {
        [DisplayName("ИД точки на карте сети")]
        public int id { get; set; }
        [DisplayName("Наименование устройства"), FRequired, FStringLength(30)]
        public string dev_name { get; set; }
        [DisplayName("Тип узла"), FRequired]
        public Flare.Controls.NetworkPointType? dev_type { get; set; }
        [DisplayName("IP адрес"), FStringLength(15)]
        public string dev_ip { get; set; }
        [DisplayName("Позиция X устройства на карте")]
        public double pointA_X { get; set; }
        [DisplayName("Позиция Y устройства на карте")]
        public double pointB_Y { get; set; }
    }
    class equipments : Validation
    {
        [DisplayName("ИД устройства")]
        public int id_equipment { get; set; }
        [DisplayName("Модель"),FRequired]
        public int? id_model { get; set; }
        [DisplayName("Комната"), FRequired]
        public int? id_room { get; set; }
        [DisplayName("Инвентарный номер"), FStringLength(50)]
        public string inventory_number { get; set; }
        [DisplayName("Заводской номер"), FStringLength(50)]
        public string factory_number { get; set; }
        [DisplayName("Примечание")]
        public string description { get; set; }
        [DisplayName("Дата создания записи"), FRequired]
        public DateTime? date_create { get; set; }
    }
    class equipment_type : Validation
    {
        [DisplayName("ИД типа устройства")]
        public int id_type { get; set; }
        [DisplayName("Тип устройства"), FStringLength(50)]
        public string type { get; set; }
    }
    class equipment_mark : Validation
    {
        [DisplayName("ИД марки устройства")]
        public int id_mark { get; set; }
        [DisplayName("Тип устройства"), FRequired]
        public int? id_type { get; set; }
        [DisplayName("Марка устройства"), FStringLength(50)]
        public string mark { get; set; }
    }
    class equipment_model : Validation
    {
        [DisplayName("ИД модели устройства")]
        public int id_model { get; set; }
        [DisplayName("Марка устройства"), FRequired]
        public int? id_mark { get; set; }
        [DisplayName("Модель устройства"), FStringLength(50)]
        public string model { get; set; }
    }
    class equipments_move_history: Validation
    {
        [DisplayNameAttribute("ИД переноса")]
        public int? id_move { get; set; }
        [DisplayNameAttribute("ИД переноса"), FRequired]
        public int? id_equipment { get; set; }
        [DisplayNameAttribute("Дата перемещения"), FRequired]
        public DateTime? move_date { get; set; }
        [DisplayNameAttribute("Комната выдачи"), FRequired]
        public string from_room { get; set; }
        [DisplayNameAttribute("Комната приемки"), FRequired]
        public string to_room { get; set; }
        [DisplayNameAttribute("Примечание")]
        public string description { get; set; }
    }
    class general_room : Validation
    {
        [DisplayName("ИД комнаты")]
        public int id_room { get; set; }
        [DisplayName("Отдел"), FRequired]
        public int? id_department { get; set; }
        [DisplayName("Комната"), FStringLength(50)]
        public string room { get; set; }
    }
    class general_department : Validation
    {
        [DisplayName("ИД отдела")]
        public int id_department { get; set; }
        [DisplayName("Отдел"), FRequired, FStringLength(50)]
        public string department { get; set; }
        [DisplayName("Адрес"), FRequired]
        public string department_address { get; set; }
        [DisplayName("Контактное лицо"), FRequired, FStringLength(50)]
        public string department_contact { get; set; }
        [DisplayName("Контактный телефон"), FRequired, FStringLength(50)]
        public string department_contact_phone { get; set; }
    }

    abstract class FValidationAttribute : ValidationAttribute
    {
        public abstract bool IsValid(string attributename, object value);
    }
    class FStringLength : FValidationAttribute
    {
        readonly int _maxlength;
        public FStringLength(int maxlength)
        {
            _maxlength = maxlength;
        }
        public override bool IsValid(string attributename, object value)
        {
            this.ErrorMessage = string.Format("Превышена максимальная длина поля [{0}]. Максимум {1} символов)", attributename, _maxlength);
            if (value == null || value.ToString().Length <= _maxlength)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
    }
    class FRegExp : FValidationAttribute
    {
        readonly string _pattern;
        public FRegExp(string pattern)
        {
            _pattern = pattern;
        }
        public override bool IsValid(string attributename, object value)
        {
            this.ErrorMessage = string.Format("Поле [{0}] имеет неверный формат", attributename);
            if (value != null)
            {
                if (System.Text.RegularExpressions.Regex.IsMatch((string)value, _pattern)) return true;
                return false;;
            }
            else
            {
                return true;
            }
        }
    }
    class FRequired : FValidationAttribute
    {
        public override bool IsValid(string attributename, object value)
        {
            this.ErrorMessage = string.Format("Значение поля [{0}] должно быть задано", attributename);
            if (value == null) return false;
            return true;
        }
    }
    class Validation
    {
        public IEnumerable<string> Validate()
        {
            var t = this;
            foreach (PropertyDescriptor propertyDescriptor in TypeDescriptor.GetProperties(this))
            {
                var errors = propertyDescriptor.Attributes.OfType<FValidationAttribute>()
                    .Where(x => !x.IsValid(propertyDescriptor.DisplayName, propertyDescriptor.GetValue(t)))
                    .Select(x => x.ErrorMessage);
                foreach (string e in errors)
                {
                    yield return e;
                }
            }
        }
    }
}
